//
//  AmsClient.m
//  IVCS
//
//  Created by nfl on 2022/2/28.
//  Copyright © 2022 zco user. All rights reserved.
//

#import "AmsClient.h"
#import <SocketIO/SocketIO-Swift.h>

@interface AmsClient()<NSObject>

/// socketManager
@property(strong,nonatomic)SocketManager* manager;

/// socektIOClient
@property(strong,nonatomic)SocketIOClient *socket;

/// socketIo is connected default = false;
@property(assign,nonatomic)BOOL connected;

@end

@implementation AmsClient

NSString const *AckOK = @"ok";
NSInteger const AckOKCode = 200;

relizeSingleInstance(Ams)

-(void)connectWithUrl:(NSString *)baseUrl andToken:(NSString *)token complete:(completeBlock)complete{
    self.baseUrl = baseUrl ;
    NSString *connectUrl = [NSString stringWithFormat:@"%@/socket.io/?token=%@&servicePath=_ivcs_ams&EIO=3&transport=websocket",baseUrl,token];
    NSURL *url = [[NSURL alloc] initWithString:connectUrl];
    
    NSDictionary *header = @{
        @"token":token,
        @"servicePath":@"_ivcs_ams"
    };
    // TODO 后续我们要支持reconnect，你要看下怎么实现的。@reconnect=YES。。目前默认重连次数是10次。允许重连10次。所以后面需要监听Reconnect/reconnect-error等相关事件
    NSDictionary *config = @{
                             @"log": @YES,
                             // @"forcePolling": @NO,
                             //@"compress": @YES
                             @"forceWebsockets":@YES,
                             @"reconnect":@NO,
                             @"secure":@NO,
                             @"force new connection":@YES,
                             //@"query":query,
                             @"connectParams":header,
                             @"sessionDelegate":self,
                             // @"selfSigned":@YES,
                             // @"extraHeaders":header
                             };
    NSLog(@"connect url,%@,,para,,%@",connectUrl,config);
    self.manager = [[SocketManager alloc] initWithSocketURL:url config:config];
    self.socket = self.manager.defaultSocket;
    
    CallBackObject *callBackResult =[[CallBackObject alloc] init];
    
    NSUUID *uuid = [self.socket on:@"connect" callback:^(NSArray* data, SocketAckEmitter* ack) {
        MyLog(@"%@,socketio connected,data:%@",self.socket,data);
        self.accessToken = token;
        self.connected = true;
        [[self.socket emitWithAck:@"agent-login" with:@[]] timingOutAfter:0 callback:^(NSArray * _Nonnull result) {
            if (result.count > 1 && [result[1] isKindOfClass:NSDictionary.class]) {
                callBackResult.data = result[1];
            }
            if ([AckOK isEqualToString: result[0]]) {
                callBackResult.code = AckOKCode;
                complete(callBackResult);
            }else{
                callBackResult.message = @"ams's agent login failed";
                complete(callBackResult);
            }
        }];
    }];
    NSLog(@"ams connect uuid:%@" , uuid);
    
    [self.socket on:@"connect_error" callback:^(NSArray * _Nonnull data, SocketAckEmitter * _Nonnull ack) {
        MyLog(@"ams 连接错误：%@ , %@" , data , ack);
        callBackResult.message = @"ams connect error";
        complete(callBackResult);
    }];
    
    [self.socket on:@"ring" callback:^(NSArray * _Nonnull data, SocketAckEmitter * _Nonnull ack) {
        MyLog(@"ams 响铃：%@ , %@" , [AmsClient toJsonString:data[0]] , ack);
        self.ringData =[[ZcoModelRing alloc] initWithDictionary:data[0]];
        if (self.delegate && [self.delegate respondsToSelector:@selector(onRing:)]) {
            [self.delegate onRing:self.ringData];
        }
    }];
    
    [self.socket on:@"drop" callback:^(NSArray * _Nonnull data, SocketAckEmitter * _Nonnull ack) {
        MyLog(@"ams 挂断：%@ , %@" , data , ack);
    }];
    
    [self.socket on:@"replaced" callback:^(NSArray * _Nonnull data, SocketAckEmitter * _Nonnull ack) {
        MyLog(@"ams replaced：%@ , %@" , data , ack);
    }];
    
    [self.socket on:@"stop-ringing" callback:^(NSArray * _Nonnull data, SocketAckEmitter * _Nonnull ack) {
        MyLog(@"ams 响铃停止：%@ , %@" , data , ack);
        if (self.delegate && [self.delegate respondsToSelector:@selector(onCancelRing)]) {
            [self.delegate onCancelRing];
        }
    }];
    
    [self.socket on:@"error" callback:^(NSArray * _Nonnull data, SocketAckEmitter * _Nonnull ack) {
        MyLog(@"%@,socketio error,data:%@",self.socket,data);
        callBackResult.code = 301;
        callBackResult.message = @"ams error";
        complete(callBackResult);
        [self.socket disconnect];
    }];
    
    [self.socket on:@"connect_timeout" callback:^(NSArray * _Nonnull data, SocketAckEmitter * _Nonnull ack) {
        MyLog(@"%@,socketio connect_timeout,data:%@",self.socket,data);
        callBackResult.code = 301;
        callBackResult.message = @"ams connect timeout";
        complete(callBackResult);
        [self.socket disconnect];
    }];

    [self.socket on:@"disconnect" callback:^(NSArray * _Nonnull data, SocketAckEmitter * _Nonnull ack) {
        MyLog(@"%@,socketio disconnect,data:%@",self.socket,data);
        self.connected = false;
      }];
    
    [self.socket connect];
}

-(void)sendMessage:(NSString *)type withData:(NSDictionary *_Nullable)data complete:(completeBlock)complete{
    MyLog(@"ams sendMessage:type = %@ , data = %@" , type , data);
    NSArray *items ;
    if (data) {
        items = [NSArray arrayWithObject:data];
    }else{
        items = nil;
    }
    [[self.socket emitWithAck:type with:items] timingOutAfter:0
    callback:^(NSArray * _Nonnull data) {
        MyLog(@"callback data : %@" , data);
        CallBackObject *callBackResult =[[CallBackObject alloc] init];
        if ([AckOK isEqualToString:data[0]]) {
            callBackResult.code = AckOKCode;
        }
        if (data.count > 1) {
            if ([data[1] isKindOfClass:NSDictionary.class]) {
                callBackResult.data = data[1];
            }
            else if ([data[1] isKindOfClass:NSString.class]){
                callBackResult.message = data[1];
            }
        }
        complete(callBackResult);
    }];
}

+(NSString *)toJsonString:(id)data{
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:&error];
    NSString *jsonString;
    if (!jsonData) {
        MyLog(@"%@",error);
    } else {
        jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    NSRange range = {0,jsonString.length};
    //去掉字符串中的空格
    [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
    NSRange range2 = {0,mutStr.length};
    //去掉字符串中的换行符
    [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
    return mutStr;
}

@end
